﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WCrawlerLib
{
    public static class WebControlsEx
    {
        public static int IndexOf(this DataKeyArray dataKeyArray, string keyName, object value)
        {
            if (dataKeyArray.Count < 1) throw new InvalidOperationException("DataKeyArray contains no elements.");
            List<DataKey> keys = dataKeyArray.Cast<DataKey>().ToList();
            var key = keys.AsEnumerable<DataKey>().SingleOrDefault(k => k[keyName].ToString() == value.ToString());
            if (key == null) 
                return -1;
            return keys.IndexOf(key);

            //int index = -1;
            //foreach(DataKey key in keys){
            //    if (key[keyName].ToString() == value.ToString())
            //    {
            //        index = keys.IndexOf(key);
            //        break;
            //    }
            //}
            //return index;
        }
    }

    public static class PredicateBuilder
    {
        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                            Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                             Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }

    ///// <summary>
    ///// Extension Linq for ForumThread
    ///// </summary>
    //public static class ForumThreadExtensionLinq
    //{
    //    public static IQueryable<ForumThread> WhereThreadPost(this IQueryable<ForumThread> query, IQueryable<ThreadPost> threadPostQuery)
    //    {
    //        //    int? value = int.Parse(postDetailsId);
    //        //    query = query.Where(p => p.PostDetailsId == value);
    //        //return query;
    //    }
    //}

    /// <summary>
    /// Extension Linq for ThreadPost
    /// </summary>
    public static class ThreadPostExtensionLinq
    {
        public static IQueryable<ThreadPost> WherePostDetails(this IQueryable<ThreadPost> query, string postDetailsId)
        {
            if (!string.IsNullOrEmpty(postDetailsId))
            {
                int? value = int.Parse(postDetailsId);
                query = query.Where(p => p.PostDetailsId == value);
            }
            return query;
        }

        public static IQueryable<ThreadPost> WherePost(this IQueryable<ThreadPost> query, string postId)
        {
            if (!string.IsNullOrEmpty(postId))
            {
                int? value = int.Parse(postId);
                query = query.Where(p => p.PostDetail.PostId == value);
            }
            return query;
        }

        public static IQueryable<ThreadPost> WhereForum(this IQueryable<ThreadPost> query, string forumId)
        {
            if (!string.IsNullOrEmpty(forumId))
            {
                int? value = int.Parse(forumId);
                query = query.Where(p => p.ForumThread.ForumId == value);
            }
            return query;
        }
    }
    /// <summary>
    /// Extension Linq for Forum class
    /// </summary>
    public static class PostDetailsExtensionLinq
    {
        public static IQueryable<PostDetail> WherePost(this IQueryable<PostDetail> query, string postId)
        {
            if (!string.IsNullOrEmpty(postId))
            {
                int? value = int.Parse(postId);
                query = query.Where(p => p.PostId == value);
            }
            return query;
        }
    }

    /// <summary>
    /// Extension Linq for Forum class
    /// </summary>
    public static class PostExtensionLinq
    {
        public static IQueryable<Post> WhereTopic(this IQueryable<Post> query, string topicIds)
        {
            LinqDataClassesDataContext dc = new LinqDataClassesDataContext();
            List<string> topicIdList = topicIds.Split(new char[] { '|' }).ToList();
            query = (from p in dc.Posts
                     where topicIdList.Contains(p.TopicId.ToString())
                     select p).OrderBy(t => t.PostId);//(t => t.Topic.TopicOrder);

            return query;
        }

        public static IQueryable<Post> IsApproved(this IQueryable<Post> query, int isApproved)
        {
            if (isApproved == 1) //Approved
                query = query.Where(p => p.IsApproved == true);
            else if (isApproved == 2) //Not approved
                query = query.Where(p => p.IsApproved == false);
            return query;
        }
    }

    /// <summary>
    /// Extension Linq for Forum class
    /// </summary>
    public static class ForumExtensionLinq
    {
        public static IQueryable<Forum> IsPosted(this IQueryable<Forum> query, int postId, int isPosted)
        {
            LinqDataClassesDataContext dc = new LinqDataClassesDataContext();
            if (isPosted == 0) //select all
            {
                //Do nothing
            }
            else if (isPosted == 1) //if unposted
            {
                query = from p in query
                        where !(from q in dc.ThreadPosts
                                where q.PostDetail.PostId == postId
                                    && q.IsFirstPost == true
                                select q.ForumThread.ForumId).Contains(p.ForumId)
                        select p;
            }
            else //if posted
            {
                query = from p in query
                        where  (from q in dc.ThreadPosts
                                where q.PostDetail.PostId == postId
                                    && q.IsFirstPost == true
                                select q.ForumThread.ForumId).Contains(p.ForumId)
                        select p;
            }
            return query;
        }

        public static IQueryable<Forum> ContainsUrl(this IQueryable<Forum> query, string value)
        {
            if (!string.IsNullOrEmpty(value))
            {
                query = query.Where(p => p.ForumUrl.Contains(value));
            }
            return query;
        }

        public static IQueryable<Forum> WhereLocation(this IQueryable<Forum> query, string valueId)
        {
            if (!string.IsNullOrEmpty(valueId))
            {
                int? value = int.Parse(valueId);
                query = query.Where(p => p.LocationId == value);
            }
            return query;
        }

        public static IQueryable<Forum> WhereForumType(this IQueryable<Forum> query, string valueId)
        {
            if (!string.IsNullOrEmpty(valueId))
            {
                int? value = int.Parse(valueId);
                query = query.Where(p => p.ForumTypeId == value);
            }
            return query;
        }

        public static IQueryable<Forum> WhereContentType(this IQueryable<Forum> query, string valueId)
        {
            if (!string.IsNullOrEmpty(valueId))
            {
                int? value = int.Parse(valueId);
                query = query.Where(p => p.ContentTypeId == value);
            }
            return query;
        }

        public static IQueryable<Forum> WhereLanguage(this IQueryable<Forum> query, string valueId)
        {
            if (!string.IsNullOrEmpty(valueId))
            {
                int? value = int.Parse(valueId);
                query = query.Where(p => p.LanguageId == value);
            }
            return query;
        }

        public static IQueryable<Forum> WhereGroup(this IQueryable<Forum> query, string valueId)
        {
            if (!string.IsNullOrEmpty(valueId))
            {
                int? value = int.Parse(valueId);
                query = query.Where(p => p.GroupId == value);
            }
            return query;
        }

        public static IQueryable<Forum> IsApproved(this IQueryable<Forum> query, bool valueId)
        {
            query = query.Where(p => p.IsApproved == valueId);
            return query;
        }

        public static IQueryable<Forum> IsLoginStatus(this IQueryable<Forum> query, string valueId)
        {
            if (valueId != "")
            {
                bool value = int.Parse(valueId) == 1 ?  true : false;
                query = query.Where(p => p.LoginStatus == value);
            }
            return query;
        }

        public static IQueryable<Forum> WhereStatusCode(this IQueryable<Forum> query, string valueId)
        {
            if (!string.IsNullOrEmpty(valueId))
            {
                int? value = int.Parse(valueId);
                query = query.Where(p => p.StatusCodeId == value);
            }
            return query;
        }

        public static IQueryable<Forum> IsTags(this IQueryable<Forum> query, bool valueId)
        {
            if (valueId)
                query = query.Where(p => p.IsTags == valueId);
            return query;
        }

        public static IQueryable<Forum> IsIcons(this IQueryable<Forum> query, bool valueId)
        {
            if (valueId)
                query = query.Where(p => p.IsIcons == valueId);
            return query;
        }

        public static IQueryable<Forum> IsReCaptcha(this IQueryable<Forum> query, bool valueId)
        {
            if (valueId)
                query = query.Where(p => p.IsReCaptcha == valueId);
            return query;
        }

        public static IQueryable<Forum> IsHideTag(this IQueryable<Forum> query, bool valueId)
        {
            if (valueId)
                query = query.Where(p => p.IsHideTag == valueId);
            return query;
        }

        public static IQueryable<Forum> IsPrefix(this IQueryable<Forum> query, bool valueId)
        {
            if (valueId)
                query = query.Where(p => p.IsPrefix == valueId);
            return query;
        }

        public static IQueryable<Forum> IsHostConstraint(this IQueryable<Forum> query, bool valueId)
        {
            if (valueId)
                query = query.Where(p => p.IsPrefix == valueId);
            return query;
        }
    }
}